
#include <stdio.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_pwm.h"
#include "iot_errno.h"
#include "hi_io.h"

#define RED_LED_PIN_NAME 2
#define GREEN_LED_PIN_NAME 8
#define BLUE_LED_PIN_NAME 7
#define BUTTON_PIN_NAME 14

#define IOT_PWM_DUTY_MAX 100
#define PWM_FREQ_DIVITION 64000
#define DELAY_US 50000
#define STACK_SIZE (4096)
#define PWM_PORT_RED 2
#define PWM_PORT_GREEN 0
#define PWM_PORT_BLUE 1
#define DOUBLE (2)

/* 初始化按键GPIO */
static void InitButton(void)
{
    // 按键初始化
    IoTGpioInit(BUTTON_PIN_NAME);
    // 模式设置为标准GPIO
    hi_io_set_func(BUTTON_PIN_NAME, HI_IO_FUNC_GPIO_14_GPIO);
    // 设置为输入
    IoTGpioSetDir(BUTTON_PIN_NAME, IOT_GPIO_DIR_IN);
    // 拉高GPIO14电平等待后续按键事件触发
    hi_io_set_pull(BUTTON_PIN_NAME, HI_IO_PULL_UP);
}

/* 等待按键按下并释放 */
static void WaitButtonPress(void)
{
    IotGpioValue val;
    
    // 等待按键按下
    while (1) {
        IoTGpioGetInputVal(BUTTON_PIN_NAME, &val);
        if (val == IOT_GPIO_VALUE0) {
            break;
        }
        usleep(10000);
    }
    usleep(100000); // 消抖
    
    // 等待按键释放
    while (1) {
        IoTGpioGetInputVal(BUTTON_PIN_NAME, &val);
        if (val == IOT_GPIO_VALUE1) {
            break;
        }
        usleep(10000);
    }
    usleep(100000); // 消抖
}

static void LedButtonDemoTask(void *arg)
{
    (void)arg;
    
    // 初始化按键
    InitButton();
    
    // 初始化RGB LED
    IoTGpioInit(RED_LED_PIN_NAME);
    IoTGpioInit(GREEN_LED_PIN_NAME);
    IoTGpioInit(BLUE_LED_PIN_NAME);

    while (1) {
        printf("Press button to start RGB LED sequence...\n");
        WaitButtonPress();
        
        // 红色渐变
        printf("Red LED breathing...\n");
        hi_io_set_func(RED_LED_PIN_NAME, HI_IO_FUNC_GPIO_2_PWM2_OUT);
        IoTPwmInit(PWM_PORT_RED);
        for (int i = 1; i < IOT_PWM_DUTY_MAX; i *= DOUBLE) {
            IoTPwmStart(PWM_PORT_RED, i, PWM_FREQ_DIVITION);
            usleep(DELAY_US);
        }
        for (int i = IOT_PWM_DUTY_MAX; i > 1; i /= DOUBLE) {
            IoTPwmStart(PWM_PORT_RED, i, PWM_FREQ_DIVITION);
            usleep(DELAY_US);
        }
        IoTPwmStop(PWM_PORT_RED);
        
        WaitButtonPress();
        
        // 绿色渐变
        printf("Green LED breathing...\n");
        hi_io_set_func(GREEN_LED_PIN_NAME, HI_IO_FUNC_GPIO_9_PWM0_OUT);
        IoTPwmInit(PWM_PORT_GREEN);
        for (int i = 1; i < IOT_PWM_DUTY_MAX; i *= DOUBLE) {
            IoTPwmStart(PWM_PORT_GREEN, i, PWM_FREQ_DIVITION);
            usleep(DELAY_US);
        }
        for (int i = IOT_PWM_DUTY_MAX; i > 1; i /= DOUBLE) {
            IoTPwmStart(PWM_PORT_GREEN, i, PWM_FREQ_DIVITION);
            usleep(DELAY_US);
        }
        IoTPwmStop(PWM_PORT_GREEN);
        
        WaitButtonPress();
        
        // 蓝色渐变
        printf("Blue LED breathing...\n");
        hi_io_set_func(BLUE_LED_PIN_NAME, HI_IO_FUNC_GPIO_8_PWM1_OUT);
        IoTPwmInit(PWM_PORT_BLUE);
        for (int i = 1; i < IOT_PWM_DUTY_MAX; i *= DOUBLE) {
            IoTPwmStart(PWM_PORT_BLUE, i, PWM_FREQ_DIVITION);
            usleep(DELAY_US);
        }
        for (int i = IOT_PWM_DUTY_MAX; i > 1; i /= DOUBLE) {
            IoTPwmStart(PWM_PORT_BLUE, i, PWM_FREQ_DIVITION);
            usleep(DELAY_US);
        }
        IoTPwmStop(PWM_PORT_BLUE);
    }
}

static void LedButtonDemo(void)
{
    osThreadAttr_t attr;

    attr.name = "LedButtonDemoTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = STACK_SIZE;
    attr.priority = osPriorityNormal;

    if (osThreadNew(LedButtonDemoTask, NULL, &attr) == NULL) {
        printf("[LedButtonDemo] Failed to create LedButtonDemoTask!\n");
    }
}

APP_FEATURE_INIT(LedButtonDemo);